var componentModule = require("../common/component"), utils = require("../common/utils");

(0, componentModule.VantComponent)({
    classes: [ "active-class" ],
    properties: {
        valueKey: String,
        className: String,
        itemHeight: Number,
        visibleItemCount: Number,
        initialOptions: {
            type: Array,
            value: []
        },
        defaultIndex: {
            type: Number,
            value: 0
        }
    },
    data: {
        startY: 0,
        offset: 0,
        duration: 0,
        startOffset: 0,
        options: [],
        currentIndex: 0
    },
    created: function() {
        var componentInstance = this, componentData = this.data, defaultIndex = componentData.defaultIndex, initialOptions = componentData.initialOptions;
        this.set({
            currentIndex: defaultIndex,
            options: initialOptions
        }).then(function() {
            componentInstance.setIndex(defaultIndex);
        });
    },
    computed: {
        count: function() {
            return this.data.options.length;
        },
        baseOffset: function() {
            var componentData = this.data;
            return componentData.itemHeight * (componentData.visibleItemCount - 1) / 2;
        },
        wrapperStyle: function() {
            var componentData = this.data;
            return [ "transition: " + componentData.duration + "ms", "transform: translate3d(0, " + (componentData.offset + componentData.baseOffset) + "px, 0)", "line-height: " + componentData.itemHeight + "px" ].join("; ");
        }
    },
    observers: {
        defaultIndex: function(newDefaultIndex) {
            this.setIndex(newDefaultIndex);
        }
    },
    methods: {
        onTouchStart: function(event) {
            this.set({
                startY: event.touches[0].clientY,
                startOffset: this.data.offset,
                duration: 0
            });
        },
        onTouchMove: function(event) {
            var componentData = this.data, touchY = event.touches[0].clientY;
            this.set({
                offset: (0, utils.range)(componentData.startOffset + touchY - componentData.startY, -componentData.count * componentData.itemHeight, componentData.itemHeight)
            });
        },
        onTouchEnd: function() {
            var componentData = this.data;
            if (componentData.offset !== componentData.startOffset) {
                this.set({
                    duration: 200
                });
                var newIndex = (0, utils.range)(Math.round(-componentData.offset / componentData.itemHeight), 0, componentData.count - 1);
                this.setIndex(newIndex, true);
            }
        },
        onClickItem: function(event) {
            var index = event.currentTarget.dataset.index;
            this.setIndex(index, true);
        },
        adjustIndex: function(index) {
            for (var componentData = this.data, newIndex = index = (0, utils.range)(index, 0, componentData.count); newIndex < componentData.count; newIndex++) if (!this.isDisabled(componentData.options[newIndex])) return newIndex;
            for (var i = newIndex - 1; 0 <= i; i--) if (!this.isDisabled(componentData.options[i])) return i;
        },
        isDisabled: function(option) {
            return (0, utils.isObj)(option) && option.disabled;
        },
        getOptionText: function(option) {
            var componentData = this.data;
            return (0, utils.isObj)(option) && componentData.valueKey in option ? option[componentData.valueKey] : option;
        },
        setIndex: function(index, shouldEmit) {
            var componentInstance = this, componentData = this.data, newIndex = -(index = this.adjustIndex(index) || 0) * componentData.itemHeight;
            return index !== componentData.currentIndex ? this.set({
                offset: newIndex,
                currentIndex: index
            }).then(function() {
                shouldEmit && componentInstance.$emit("change", index);
            }) : this.set({
                offset: newIndex
            });
        },
        setValue: function(value) {
            for (var options = this.data.options, i = 0; i < options.length; i++) if (this.getOptionText(options[i]) === value) return this.setIndex(i);
            return Promise.resolve();
        },
        getValue: function() {
            var componentData = this.data;
            return componentData.options[componentData.currentIndex];
        }
    }
});